import logging
import json
import uuid
from datetime import datetime
from . import db
from .new_models import (
    CareElderDemand,
    CareGbNursingAction,
    DigitalEmployeeSkills,
    AppUser,
    AppUserDetail,
    CareScheduleResultOld,
    CareTimeSlotOld,
)
from .care_utils import CareUtils

# 设置日志
logger = logging.getLogger(__name__)


class DatabaseAdapter:
    """数据库适配器，处理新旧数据库表之间的转换"""

    @staticmethod
    def save_schedule_result(elder_id, schedule_date, schedule_data, plan_date=None, batch_number=None):
        """保存照护计划总表

        保存到care_schedule_results_old表

        Args:
            elder_id: 老人ID
            schedule_date: 排班日期
            schedule_data: 排班数据
            plan_date: 计划日期
            batch_number: 批次号

        Returns:
            (care_schedule_result, care_schedule_result): 保存的记录（返回两次相同的对象以保持兼容性）
        """
        try:
            # 生成唯一ID
            result_id = str(uuid.uuid4())
            current_time = datetime.now()

            # 如果schedule_data是字符串，尝试解析为JSON
            if isinstance(schedule_data, str):
                try:
                    schedule_data_list = json.loads(schedule_data)
                except json.JSONDecodeError:
                    logger.warning(f"无法解析schedule_data为JSON: {schedule_data}")
                    schedule_data_list = None
            else:
                schedule_data_list = schedule_data

            # 如果成功解析为列表，处理每个时间段条目
            if isinstance(schedule_data_list, list):
                for entry in schedule_data_list:
                    if isinstance(entry, dict) and 'ActivityId' in entry and 'Activity' in entry:
                        activity_id = entry['ActivityId']
                        # 如果活动ID不是10（睡眠）或8（日常生活），尝试从digital_employee_skills表获取活动名称
                        if activity_id != "10" and activity_id != 10 and activity_id != "8" and activity_id != 8:
                            # 获取护理动作详情
                            action = DatabaseAdapter.get_nursing_action(activity_id)
                            if action and 'activity_name' in action:
                                # 使用digital_employee_skills表中的活动名称
                                entry['Activity'] = action['activity_name']
                                logger.info(f"总表中使用digital_employee_skills表中的活动名称: {action['activity_name']}")

                # 将修改后的数据转换回JSON字符串，确保使用原始格式
                # 如果schedule_data_list已经是列表，直接使用它，不需要再次转换为JSON字符串
                # 这样可以避免双重转义的问题
                schedule_data = schedule_data_list

            # 保存到care_schedule_results_old表
            care_schedule_result = CareScheduleResultOld(
                id=result_id,
                elder=elder_id,
                schedule_date=schedule_date,
                schedule_data=schedule_data,
                plan_date=plan_date,
                batch_number=batch_number,
                create_time=current_time,
                update_time=current_time,
                status="active"
            )

            # 添加到数据库
            db.session.add(care_schedule_result)
            db.session.commit()

            logger.info(f"保存照护计划总表成功，ID: {result_id}")
            # 返回相同的对象两次，以保持与原接口的兼容性
            return care_schedule_result, care_schedule_result

        except Exception as e:
            db.session.rollback()
            logger.error(f"保存照护计划总表时出错: {str(e)}")
            raise

    @staticmethod
    def save_time_slot(
        schedule_result_id, elder_id, time_slot, activity, activity_id,
        caregiver, caregiver_id, time_order, schedule_date,
        plan_date=None, batch_number=None
    ):
        """保存照护计划分表

        保存到care_time_slots_old表

        Args:
            schedule_result_id: 照护计划总表ID
            elder_id: 老人ID
            time_slot: 时间段
            activity: 活动名称
            activity_id: 活动ID
            caregiver: 护理员名称
            caregiver_id: 护理员ID
            time_order: 时间顺序
            schedule_date: 排班日期
            plan_date: 计划日期
            batch_number: 批次号

        Returns:
            (care_time_slot, care_time_slot): 保存的记录（返回两次相同的对象以保持兼容性）
        """
        try:
            # 生成唯一ID
            slot_id = str(uuid.uuid4())
            current_time = datetime.now()

            # 如果活动ID不是10（睡眠）或8（日常生活），尝试从digital_employee_skills表获取活动名称
            if activity_id != "10" and activity_id != 10 and activity_id != "8" and activity_id != 8:
                # 获取护理动作详情
                action = DatabaseAdapter.get_nursing_action(activity_id)
                if action and 'activity_name' in action:
                    # 使用digital_employee_skills表中的活动名称
                    activity = action['activity_name']
                    logger.info(f"使用digital_employee_skills表中的活动名称: {activity}")

            # 保存到care_time_slots_old表
            care_time_slot = CareTimeSlotOld(
                id=slot_id,
                schedule_result_id=schedule_result_id,
                elder=elder_id,
                time_slot=time_slot,
                activity=activity,
                activity_id=activity_id,
                caregiver=caregiver,
                caregiver_id=caregiver_id,
                time_order=time_order,
                schedule_date=schedule_date,
                plan_date=plan_date,
                batch_number=batch_number,
                create_time=current_time,
                update_time=current_time,
                status="active"
            )

            # 添加到数据库
            db.session.add(care_time_slot)
            db.session.commit()

            logger.debug(f"保存照护计划分表成功，ID: {slot_id}")
            # 返回相同的对象两次，以保持与原接口的兼容性
            return care_time_slot, care_time_slot

        except Exception as e:
            db.session.rollback()
            logger.error(f"保存照护计划分表时出错: {str(e)}")
            raise

    @staticmethod
    def get_elder_demands():
        """获取所有需要安排的老人

        从care_elder_demand表中获取arrange='1'的老人

        Returns:
            老人列表
        """
        try:
            # 从care_elder_demand表获取
            elders = CareElderDemand.query.filter_by(arrange="1").all()
            logger.info(f"从care_elder_demand表找到 {len(elders)} 个需要安排的老人")
            return elders
        except Exception as e:
            logger.error(f"获取老人需求时出错: {str(e)}")
            return []

    @staticmethod
    def get_nursing_action(action_id):
        """获取护理动作

        先尝试直接从digital_employee_skills表获取活动名称
        如果找不到，再从care_gb_nursing_action表获取

        Args:
            action_id: 护理动作ID

        Returns:
            护理动作信息，包含name和nursing_id
        """
        try:
            # 首先尝试直接从digital_employee_skills表获取活动名称
            try:
                skill = DigitalEmployeeSkills.query.filter_by(id=int(action_id)).first()
                if skill:
                    # 如果找到了对应的技能，直接使用其名称
                    activity_name = skill.name
                    # 如果活动名称的第一个字符是数字，就将其去掉
                    if activity_name and len(activity_name) > 0 and activity_name[0].isdigit():
                        activity_name = activity_name[1:].strip()
                        logger.info(f"去掉活动名称前面的数字，原名称: {skill.name}, 新名称: {activity_name}")

                    logger.info(f"直接从digital_employee_skills表获取到活动名称: {activity_name}")
                    return {
                        'id': action_id,
                        'name': activity_name,
                        'level': skill.level if hasattr(skill, 'level') else 1,
                        'nursing_id': str(skill.id),
                        'activity_name': activity_name
                    }
            except (ValueError, TypeError):
                # 如果action_id不是有效的整数，忽略错误
                logger.warning(f"无效的action_id: {action_id}，无法直接从digital_employee_skills表获取")

            # 如果直接获取失败，尝试从care_gb_nursing_action表获取
            action = CareGbNursingAction.query.filter_by(id=action_id).first()

            # 如果care_gb_nursing_action表中没有数据，返回默认活动
            if not action:
                logger.warning(f"care_gb_nursing_action表中没有ID为{action_id}的护理动作，使用默认活动")
                return {
                    'id': action_id,
                    'name': "老年人照护活动",
                    'level': 1,
                    'nursing_id': None,
                    'activity_name': "老年人照护活动"
                }

            # 如果有nursing_id，尝试从digital_employee_skills表获取活动名称
            if hasattr(action, 'nursing_id') and action.nursing_id:
                activity_name = CareUtils.get_activity_name_by_nursing_id(action.nursing_id)

                # 如果从digital_employee_skills表中找不到匹配的活动名称，使用默认名称
                if not activity_name or activity_name == "老年人照护活动":
                    logger.warning(f"在digital_employee_skills表中找不到nursing_id为{action.nursing_id}的活动名称，使用默认名称")
                    activity_name = "老年人照护活动"
            else:
                # 如果没有nursing_id，使用默认名称
                logger.warning(f"护理动作ID {action_id} 没有nursing_id，使用默认名称")
                activity_name = "老年人照护活动"

            return {
                'id': action.id,
                'name': activity_name,  # 使用digital_employee_skills表中的name字段作为活动名称
                'level': action.level if hasattr(action, 'level') else 1,
                'nursing_id': action.nursing_id if hasattr(action, 'nursing_id') else None,
                'activity_name': activity_name
            }

        except Exception as e:
            # 发生异常时，返回默认活动
            logger.error(f"获取护理动作时出错: {str(e)}")
            return {
                'id': action_id,
                'name': "老年人照护活动",
                'level': 1,
                'nursing_id': None,
                'activity_name': "老年人照护活动"
            }

    @staticmethod
    def get_caregivers():
        """获取所有护理员

        从app_user和app_user_detail表获取护理员信息

        Returns:
            护理员列表
        """
        try:
            # 从app_user和app_user_detail表获取
            caregivers = CareUtils.get_caregivers()
            logger.info(f"从app_user和app_user_detail表找到 {len(caregivers)} 名护理员")
            return caregivers
        except Exception as e:
            logger.error(f"获取护理员时出错: {str(e)}")
            return []
